NOTAS: Se dispone de los datos del SITEC ordenados cada 15 minutos por Estacion
La demanda en 13 KV del SITEC es la que soportan los trafos de la ET mas la Generacion. Por tanto, los trafos soportan lo que transforma cada uno de 132 a 13 KV.
Leer la tabla 3 de Transformadores (Guia de Referencia) y colocar ese pronostico como alternativo
Detectar automaticamente los Outliers o Atipicos (LISTO)
INFORME
Al informe se lo presento en word o lo presento con nbviewer
Si lo presento con word, tengo que pasar Tablaxls a Excel
# -*- coding: utf-8 -*-
"""
Created on Viernes 8 Octubre 2021 17:43:11
@author: Daniel Busso
"""
# Plantilla de Pre Procesado
# Cómo importar las librerías
import numpy as np
import pandas as pd
import datetime as dt
import os
# Gráficos
# ==============================================================================
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#plt.style.use('fivethirtyeight')
#from statsmodels.graphics.tsaplots import plot_acf
#from statsmodels.graphics.tsaplots import plot_pacf
# Configuración warnings
# ==============================================================================
import warnings
warnings.filterwarnings('ignore')
# Modelado y Forecasting
# ==============================================================================
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.ensemble import RandomForestRegressor
#from xgboost import XGBRegressor
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
#from sklearn.metrics import mean_absolute_percentage_error
#from skforecast.ForecasterAutoreg import ForecasterAutoreg
#from skforecast.ForecasterAutoregMultiOutput import ForecasterAutoregMultiOutput
#from skforecast.model_selection import grid_search_forecaster
#from skforecast.model_selection import time_series_spliter
#from skforecast.model_selection import cv_forecaster
#from skforecast.model_selection import backtesting_forecaster
#from skforecast.model_selection import backtesting_forecaster_intervals
# Configuracion Pandas
pd.set_option('display.max_rows', 200)
pd.set_option('display.max_columns', None)
pd.set_option('display.width', None)
pd.set_option('display.max_colwidth', -1)
pd.set_option('display.float_format', '{:.2f}'.format)
Lectura y creacion del index DateTime para tratar el DataFrame como una Serie de Tiempo
def conversion_2400(fecha):
if fecha[11:13] != '24':
return pd.to_datetime(fecha, format='%d/%m/%Y %H:%M')
fecha = fecha[0:11] + '00:' + fecha[14:]
return pd.to_datetime(fecha, format='%d/%m/%Y %H:%M') + dt.timedelta(days=1)
# EMPIEZO PROCESANDO UNA CARPETA
# AUTOMATIZAR LECTURAS DE VARIOS ARCHIVOS .PRN ANUALES
# lEER Y CONCATENAR LOS ARCHIVOS .prn DE LA CARPETA DSPractica/eetts/sanfrancisco
import os
import sys
from pathlib import Path
# ELEGIR PLATAFORMA WINDOWS LOCAL O GOOGLE COLABORATORY (la Nube)
if sys.platform == 'linux' :
from google.colab import drive
drive.mount('/content/drive', force_remount=True)
carpeta_trabajo = Path('/content/drive/Othercomputers/LENOVO/eett_prod/san_francisco/Demanda_13') # Google Colab
else:
carpeta_inicio = Path.home()
carpeta_eett = Path("eett_prod/san_francisco/Demanda_13")
carpeta_trabajo = carpeta_inicio / carpeta_eett
archivos = list(carpeta_trabajo.glob('*.prn'))
# Automatizacion de los DataFrames
dfconca = pd.DataFrame([])
for nombre_completo in archivos:
dfdatos = pd.read_fwf(nombre_completo, header=0, decimal=',')
dfconca = pd.concat([dfconca, dfdatos], ignore_index=True)
dfconca
| Fecha | Hora | MW | MVAR | MVA | Ampere | KVolt | |
|---|---|---|---|---|---|---|---|
| 0 | 01/01/2010 | 00:15 | 15.80 | 7.13 | 17.33 | 711.24 | 0.00 |
| 1 | 01/01/2010 | 00:30 | 15.63 | 6.82 | 17.05 | 706.06 | 0.00 |
| 2 | 01/01/2010 | 00:45 | 15.49 | 6.80 | 16.91 | 696.61 | 0.00 |
| 3 | 01/01/2010 | 01:00 | 15.55 | 6.81 | 16.98 | 698.32 | 0.00 |
| 4 | 01/01/2010 | 01:15 | 15.50 | 6.82 | 16.93 | 694.93 | 0.00 |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 411454 | 31/12/2021 | 23:00 | 23.25 | -2.69 | 23.41 | 980.38 | 4.46 |
| 411455 | 31/12/2021 | 23:15 | 22.86 | -3.06 | 23.07 | 971.29 | 4.44 |
| 411456 | 31/12/2021 | 23:30 | 22.66 | -3.20 | 22.89 | 972.08 | 4.43 |
| 411457 | 31/12/2021 | 23:45 | 22.77 | 7.82 | 24.08 | 993.98 | 4.45 |
| 411458 | 31/12/2021 | 24:00 | 22.49 | 7.86 | 23.82 | 981.86 | 4.45 |
411459 rows × 7 columns
archivos
[WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2010_1201.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2011_1200.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2012_1159.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2013_1157.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2014_1156.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2015_1154.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2016_1152.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2017_1151.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2018_1150.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2019_1150.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2020_1148.prn'),
WindowsPath('C:/Users/daniel/eett_prod/san_francisco/Demanda_13/MED_DEM_SANFCO13_2021_1246.prn')]
#
# BORRAMOS COLUMNAS NO USADAS
#
del dfconca['Ampere']
del dfconca['KVolt']
# GENERAMOS INDICE DE FECHAS PARA MANEJAR LA SERIE DE TIEMPO
dfconca['Fecha_Hora'] = dfconca['Fecha'] + ' ' + dfconca['Hora']
dfconca['Fecha_Hora'] = dfconca.Fecha_Hora.apply(conversion_2400) # CONVERSION DE HORA 24:00 ---> 00:00
dfconca.set_index('Fecha_Hora', inplace=True)
serie = dfconca.drop(dfconca.index[-1]) # borro la fila del nuevo anio
serie = serie.drop(columns=['Fecha', 'Hora'])
serie_ord = serie.sort_index()
datos = serie_ord.copy()
demandas = datos.copy()
demandas
| MW | MVAR | MVA | |
|---|---|---|---|
| Fecha_Hora | |||
| 2010-01-01 00:15:00 | 15.80 | 7.13 | 17.33 |
| 2010-01-01 00:30:00 | 15.63 | 6.82 | 17.05 |
| 2010-01-01 00:45:00 | 15.49 | 6.80 | 16.91 |
| 2010-01-01 01:00:00 | 15.55 | 6.81 | 16.98 |
| 2010-01-01 01:15:00 | 15.50 | 6.82 | 16.93 |
| ... | ... | ... | ... |
| 2021-12-31 22:45:00 | 23.42 | -2.79 | 23.58 |
| 2021-12-31 23:00:00 | 23.25 | -2.69 | 23.41 |
| 2021-12-31 23:15:00 | 22.86 | -3.06 | 23.07 |
| 2021-12-31 23:30:00 | 22.66 | -3.20 | 22.89 |
| 2021-12-31 23:45:00 | 22.77 | 7.82 | 24.08 |
411458 rows × 3 columns
datos
| MW | MVAR | MVA | |
|---|---|---|---|
| Fecha_Hora | |||
| 2010-01-01 00:15:00 | 15.80 | 7.13 | 17.33 |
| 2010-01-01 00:30:00 | 15.63 | 6.82 | 17.05 |
| 2010-01-01 00:45:00 | 15.49 | 6.80 | 16.91 |
| 2010-01-01 01:00:00 | 15.55 | 6.81 | 16.98 |
| 2010-01-01 01:15:00 | 15.50 | 6.82 | 16.93 |
| ... | ... | ... | ... |
| 2021-12-31 22:45:00 | 23.42 | -2.79 | 23.58 |
| 2021-12-31 23:00:00 | 23.25 | -2.69 | 23.41 |
| 2021-12-31 23:15:00 | 22.86 | -3.06 | 23.07 |
| 2021-12-31 23:30:00 | 22.66 | -3.20 | 22.89 |
| 2021-12-31 23:45:00 | 22.77 | 7.82 | 24.08 |
411458 rows × 3 columns
if datos.index.has_duplicates:
print('SI TIENE DUPLICADOS')
else:
print('NO TIENE DUPLICADOS')
NO TIENE DUPLICADOS
Si dife distinto de cero, significa que faltan registros/filas en los datos del SITEC
NOTA: Por el momento, no vamos a imputar estos Datos Faltantes ----> NO TIENE SENTIDO POR LA CANTIDAD DE DATOS
#dti2 = pd.date_range(start='2017-01-01 00:15:00', end='2018-01-01 00:00:00', freq="15min")
#
# No se si es tan completo porque a partir del anio 2016 las mediciones van cada 5 min
indice_completo = pd.date_range(start=datos.index[0], end=datos.index[-1], freq="15min")
#
dife = indice_completo.difference(datos.index)
if dife.empty == False:
print('Faltan algunas Mediciones: ', len(dife), '% Incompletas= ', (len(dife)/len(indice_completo)*100), '% Completas= ', \
(((len(indice_completo)-len(dife))/len(indice_completo))*100))
else:
print('\n')
print('Mediciones Completas: ', (((len(indice_completo)-len(dife))/len(indice_completo))*100))
Faltan algunas Mediciones: 9309 % Incompletas= 2.2123883289326396 % Completas= 97.78761167106737
dife
DatetimeIndex(['2010-08-14 00:00:00', '2010-11-10 00:15:00',
'2010-11-10 00:30:00', '2010-11-10 00:45:00',
'2010-11-10 01:00:00', '2010-11-10 01:15:00',
'2010-11-10 01:30:00', '2010-11-10 01:45:00',
'2010-11-10 02:00:00', '2010-11-10 02:15:00',
...
'2021-09-17 08:45:00', '2021-09-17 09:00:00',
'2021-09-17 09:15:00', '2021-09-17 09:30:00',
'2021-09-18 08:45:00', '2021-09-18 09:00:00',
'2021-09-18 09:15:00', '2021-09-18 09:30:00',
'2021-12-03 09:00:00', '2021-12-03 09:15:00'],
dtype='datetime64[ns]', length=9309, freq=None)
#
# OBTENGO LAS MEDICIONES FALTANTES FECHAS-HORA SIN MEDICION
dsm = pd.DataFrame({'Mediciones Faltantes':dife}, index=dife)
dsm
| Mediciones Faltantes | |
|---|---|
| 2010-08-14 00:00:00 | 2010-08-14 00:00:00 |
| 2010-11-10 00:15:00 | 2010-11-10 00:15:00 |
| 2010-11-10 00:30:00 | 2010-11-10 00:30:00 |
| 2010-11-10 00:45:00 | 2010-11-10 00:45:00 |
| 2010-11-10 01:00:00 | 2010-11-10 01:00:00 |
| ... | ... |
| 2021-09-18 09:00:00 | 2021-09-18 09:00:00 |
| 2021-09-18 09:15:00 | 2021-09-18 09:15:00 |
| 2021-09-18 09:30:00 | 2021-09-18 09:30:00 |
| 2021-12-03 09:00:00 | 2021-12-03 09:00:00 |
| 2021-12-03 09:15:00 | 2021-12-03 09:15:00 |
9309 rows × 1 columns
# AGRUPO LAS MEDICIONES FALTANTES
#
dsm['anio'] = dsm.index.year
dsm['mes'] = dsm.index.month
dsm['dia'] = dsm.index.day
dsm_grp = dsm.groupby(by=['anio','mes', 'dia'])
med_faltantes = dsm_grp.count()
med_faltantes
# MEDICIONES FALTANTES PARA UN ANIO EN PARTICULAR
#med_faltantes.loc[(2010), :]
# MEDICIONES FALTANTES PARA UN DIA EN PARTICULAR
#
#med_faltantes.loc[(2010,11,10), :]
#dsm_grp.get_group((2010, 11, 10))
#dsm_grp.groups
#dsm_grp.indices
| Mediciones Faltantes | |||
|---|---|---|---|
| anio | mes | dia | |
| 2010 | 8 | 14 | 1 |
| 11 | 10 | 95 | |
| 11 | 1 | ||
| 2011 | 2 | 3 | 1 |
| 2012 | 1 | 12 | 95 |
| ... | ... | ... | ... |
| 2021 | 8 | 13 | 5 |
| 27 | 1 | ||
| 9 | 17 | 6 | |
| 18 | 4 | ||
| 12 | 3 | 2 |
278 rows × 1 columns
dsm
| Mediciones Faltantes | anio | mes | dia | |
|---|---|---|---|---|
| 2010-08-14 00:00:00 | 2010-08-14 00:00:00 | 2010 | 8 | 14 |
| 2010-11-10 00:15:00 | 2010-11-10 00:15:00 | 2010 | 11 | 10 |
| 2010-11-10 00:30:00 | 2010-11-10 00:30:00 | 2010 | 11 | 10 |
| 2010-11-10 00:45:00 | 2010-11-10 00:45:00 | 2010 | 11 | 10 |
| 2010-11-10 01:00:00 | 2010-11-10 01:00:00 | 2010 | 11 | 10 |
| ... | ... | ... | ... | ... |
| 2021-09-18 09:00:00 | 2021-09-18 09:00:00 | 2021 | 9 | 18 |
| 2021-09-18 09:15:00 | 2021-09-18 09:15:00 | 2021 | 9 | 18 |
| 2021-09-18 09:30:00 | 2021-09-18 09:30:00 | 2021 | 9 | 18 |
| 2021-12-03 09:00:00 | 2021-12-03 09:00:00 | 2021 | 12 | 3 |
| 2021-12-03 09:15:00 | 2021-12-03 09:15:00 | 2021 | 12 | 3 |
9309 rows × 4 columns
med_faltantes.loc[(2014), :]
| Mediciones Faltantes | ||
|---|---|---|
| mes | dia | |
| 3 | 19 | 6 |
| 5 | 16 | 1 |
| 6 | 19 | 95 |
| 20 | 96 | |
| 21 | 96 | |
| 22 | 96 | |
| 23 | 1 |
Dejar para mas adelante la deteccion automatica de Errores de Medicion
# Gráfico boxplot para estacionalidad anual
# Cada Box Plot grafica el mes para los 12 anios
# Por ejemplo Octubre '10' son todos los valores de Octubre en los 12 anios
# ==============================================================================
fig, ax = plt.subplots(figsize=(10, 5))
plt.style.use('fivethirtyeight')
datos['mes'] = datos.index.month
datos.boxplot(column='MVA', by='mes', ax=ax)
datos.groupby('mes')['MVA'].median().plot(style='o-', linewidth=0.8, ax=ax)
# ESTETICA DEL GRAFICO
plt.xticks(fontsize=12) #plt.xticks(fontsize=15, rotation=90)
plt.yticks(fontsize=12)
#ax.set_ylabel('Demandas')
ax.set_title('Distribución Demandas por mes 2010 - 2021')
ax.legend()
fig.suptitle('');
# Gráfico boxplot para estacionalidad anual
# Blox Plot para todos los anios
# ==============================================================================
def Grafica_Caja(pi, pf):
plt.style.use('fivethirtyeight')
fig = plt.figure()
fig, ax = plt.subplots(figsize=(30, 5), dpi=100) # (15, 5)
# PREPARO LOS DATOS
datos['mes'] = datos.index.month
datos['anio'] = datos.index.year
datos2 = datos[pi:pf]
# GRAFICO EL BOXPLOT
datos2.boxplot(column='MVA', by=['anio','mes'], ax=ax)
# GRAFICO LA LINEA DE MEDIANA
y = datos2.groupby(by=['anio','mes'])['MVA'].median()
pos_sup = y.index.shape[0] + 1
x = np.arange(1, pos_sup)
ax.plot(x, y, lw=1.5, label='Mediana [MVA]', marker='o')
#datos3.groupby(by=['anio','mes'])['MVA'].median().plot(style='o-', linewidth=0.8, ax=ax)
# ESTETICA DEL GRAFICO
plt.xticks(fontsize=12, rotation=90) #plt.xticks(fontsize=15, rotation=90)
plt.yticks(fontsize=12)
#ax.set_ylabel('Demandas')
ax.set_title('Distribución Demandas por Mes ' +pi+' - '+pf)
ax.legend()
fig.suptitle('');
Grafica_Caja('2010', '2021')
<Figure size 432x288 with 0 Axes>
Grafica_Caja('2017', '2017')
<Figure size 432x288 with 0 Axes>
Grafica_Caja('2019', '2019')
<Figure size 432x288 with 0 Axes>
Grafica_Caja('2020', '2020')
<Figure size 432x288 with 0 Axes>
'### Remover Datos Atipicos'
# CALCULO FORMAL DE LOS LIMITES SUPERIOR E INFERIOR
# Demanda = Transformacion 132/13 Kv + Generacion Propia
# Demanda = TD1 + TD2 + TD3 + TG1 + TG2
#Pot_Ins_Tra = pd.Series([25.0, 25.0, 25.0], index=['TD1', 'TD2', 'TD3'])
#POT_INS_TRAFOS = Pot_Ins_Tra.sum()
#Pot_Ins_Gen = pd.Series([20.0, 28.0], index=['TG1', 'TG2']) # con cos fi = 0.8 TG1 = 16 MW y TG2 = 23 MW
#POT_INS_GENE = Pot_Ins_Gen.sum()
#POT_TOTAL = POT_INS_TRAFOS + POT_INS_GENE
#indice_ini = datos.index[0]
#delta = pd.Timedelta(value=90, unit='D')
#indice_fin = indice_ini + delta
#verano = datos.loc[indice_ini:indice_fin, 'MVA']
#===============================================================================================================
# LA IDEA ES CALCULAR LOS LIMITES PARA PERIODOS ESTIVALES DE 6 MESES
# PERIODO VERANO1 '2020-01-01':'2020-03-31'
# PERIODO INVIERNO '2020-04-01:2020-09-30'
# PERIODO VERANO2 '2020-10-01:2020-12-31'
#
def lim_sup(q75, q25):
IQR = q75 - q25
bigote = 3 * IQR # LO NORMAL SE USA 1.5
return (q75 + bigote)
atipicos = pd.Series([])
anios = ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021']
for anio in anios:
ver1i = anio + '-01-01 00'
ver1f = anio + '-03-31 23'
invi = anio + '-04-01 00'
invf = anio + '-09-30 23'
ver2i = anio + '-10-01 00'
ver2f = anio + '-12-31 23'
#verano1 = demandas.loc[ver1i:ver1f, 'MVA'].resample('D').max()
#invierno = demandas.loc[invi:invf, 'MVA'].resample('D').max()
#verano2 = demandas.loc[ver2i:ver2f, 'MVA'].resample('D').max()
verano1 = demandas.loc[ver1i:ver1f, 'MVA']
invierno = demandas.loc[invi:invf, 'MVA']
verano2 = demandas.loc[ver2i:ver2f, 'MVA']
lim_sup_ver1 = lim_sup(verano1.quantile(0.75), verano1.quantile(0.25))
lim_sup_inv = lim_sup(invierno.quantile(0.75), invierno.quantile(0.25))
lim_sup_ver2 = lim_sup(verano2.quantile(0.75), verano2.quantile(0.25))
# REMOVER EJEMPLOS DE ATIPICOS
#indice1 = pd.to_datetime('2010-01-01 19:08:08')
#indice = pd.to_datetime('2010-04-01 19:12:12')
#indice2 = pd.to_datetime('2010-10-01 19:14:14')
#demandas.loc[indice1, 'MVA'] = 150.0
#demandas.loc[indice, 'MVA'] = 150.0
#demandas.loc[indice2, 'MVA'] = 150.0
# GUARDAR LOS ATIPICOS A REMOVER Y LOS VALORES
atipicos_ver1 = verano1[verano1 > lim_sup_ver1]
atipicos_inv = invierno[invierno > lim_sup_inv]
atipicos_ver2 = verano2[verano2 > lim_sup_ver2]
atipicos = pd.concat([atipicos, atipicos_ver1, atipicos_inv, atipicos_ver2])
atipicos_ord = atipicos.sort_index()
#datos = demandas.drop(atipicos.index)
atipicos_ord
2017-01-27 09:30:00 75.78
2017-04-22 08:15:00 28.43
2017-04-22 08:30:00 28.23
2017-04-22 08:45:00 42.52
2017-04-22 09:00:00 41.99
...
2020-08-22 11:45:00 22.96
2020-08-22 12:15:00 22.92
2020-08-22 13:30:00 23.74
2020-08-22 13:45:00 23.29
2021-05-04 11:30:00 59.22
Length: 476, dtype: float64
#atipicos_ord['2017-01'].head(100)
#
# Datos
#
# Tengo que usar pandas. rowling
#
# BORRO DATOS ATIPICOS FALSOS
#foto = datos.loc['2017-01-27 09:30:00':'2017-01-27 09:30:00'].index
#datos = datos.drop(foto)
# BORRAMOS ANIO 01/2017
indice = datos.loc['2017-01', 'MVA'].idxmax()
datos = datos.drop(indice)
#
# BORRAMOS DATOS ANIO 10-11-12/2020
#
desde = '2020-10-06 17:15:00'
hasta = '2020-12-14 14:45:00'
indice = datos.loc[desde:hasta].index
datos = datos.drop(indice)
desde = pd.to_datetime(desde)
hasta = pd.to_datetime(hasta)
duracion = hasta - desde
print('Se borro: ', duracion, 'que equivale a tantas mediciones tomadas de a 15 min')
# BORRAMOS ANIO 05/2021
indice = datos.loc['2021-05', 'MVA'].idxmax()
datos = datos.drop(indice)
Se borro: 68 days 21:30:00 que equivale a tantas mediciones tomadas de a 15 min
# Gráfico boxplot para estacionalidad anual
# Cada Box Plot grafica el mes para los 12 anios
# Por ejemplo Octubre '10' son todos los valores de Octubre en los 12 anios
# ==============================================================================
fig, ax = plt.subplots(figsize=(10, 5))
plt.style.use('fivethirtyeight')
datos['mes'] = datos.index.month
datos.boxplot(column='MVA', by='mes', ax=ax)
datos.groupby('mes')['MVA'].median().plot(style='o-', linewidth=0.8, ax=ax)
# ESTETICA DEL GRAFICO
plt.xticks(fontsize=12) #plt.xticks(fontsize=15, rotation=90)
plt.yticks(fontsize=12)
#ax.set_ylabel('Demandas')
ax.set_title('Distribución Demandas por mes 2010 - 2021')
ax.legend()
fig.suptitle('');
# Gráfico boxplot para estacionalidad anual
# Blox Plot para todos los anios
# ==============================================================================
def Grafica_Caja(pi, pf):
plt.style.use('fivethirtyeight')
fig = plt.figure()
fig, ax = plt.subplots(figsize=(30, 5), dpi=100) # (15, 5)
# PREPARO LOS DATOS
datos['mes'] = datos.index.month
datos['anio'] = datos.index.year
datos2 = datos[pi:pf]
# GRAFICO EL BOXPLOT
datos2.boxplot(column='MVA', by=['anio','mes'], ax=ax)
# GRAFICO LA LINEA DE MEDIANA
y = datos2.groupby(by=['anio','mes'])['MVA'].median()
pos_sup = y.index.shape[0] + 1
x = np.arange(1, pos_sup)
ax.plot(x, y, lw=1.5, label='Mediana [MVA]', marker='o')
#datos3.groupby(by=['anio','mes'])['MVA'].median().plot(style='o-', linewidth=0.8, ax=ax)
# ESTETICA DEL GRAFICO
plt.xticks(fontsize=12, rotation=90) #plt.xticks(fontsize=15, rotation=90)
plt.yticks(fontsize=12)
#ax.set_ylabel('Demandas')
ax.set_title('Distribución Demandas por Mes ' +pi+' - '+pf)
ax.legend()
fig.suptitle('');
# GRAFICA MAXIMOS SEMANALES
def Grafica_xSemana(pi, pf):
z = datos.loc[pi:pf, 'MVA'].resample('W').max() # Datos
x = z.index # Tiempo
plt.style.use('fivethirtyeight')
fig = plt.figure()
fig, grafico = plt.subplots(figsize=(30, 5), dpi=100)
grafico.plot(x, z, lw=1, label='Potencia Aparente', marker='o')
grafico.set_xlabel('[ Meses ]') # Add an x-label to the axes.
grafico.set_ylabel('[ MVA ]') # Add a y-label to the axes.
grafico.set_title("POTENCIA APARENTE SEMANAL " + pi + ' ' + pf) # Add a title to the axes.
#grafico.legend() # Add a legend.
#grafico.annotate('Pico Max', xy=(01-31 14:45, 75), xytext=(01-31 15:00, 75), arrowprops=dict(facecolor='black', shrink=0.05)
#grafico.grid()
#fig.savefig("Todos_Anios_xSemana.png")
# Grafica anual de la Potencia Aparente cada 15 minutos
def Grafica_xmin(pi, pf):
y = datos.loc[pi:pf, 'MVA']
x = y.index
plt.style.use('fivethirtyeight')
fig = plt.figure()
fig, grafico = plt.subplots(figsize=(30, 5), dpi=100)
grafico.plot(x, y, lw=1.5, marker='o', label='Potencia Aparente x Minuto')
# grafico.plot(x, y, lw=1, label='Potencia Aparente', marker='o')
grafico.set_xlabel('[ Meses ]') # Add an x-label to the axes.
grafico.set_ylabel('[ MVA ]') # Add a y-label to the axes.
grafico.set_title("POTENCIA APARENTE [cada 15 minutos] " + anio) # Add a title to the axes.
#grafico.legend(loc='lower left') # Add a legend.
#grafico.grid(visible='True', which='major', axis='both', color='black', alpha=1, linewidth=0.5)
grafico.grid(visible='True', which='major', axis='both', color='black', linewidth=0.5)
grafico.grid(visible='True', which='minor', axis='both', color='black', linewidth=0.5)
x2 = pd.date_range(start=pi+'-01-01', end=pf+'-12-31', periods=5)
grafico.set_xticks(x2)
#grafico.annotate('Pico Max', xy=(01-31 14:45, 75), xytext=(01-31 15:00, 75), arrowprops=dict(facecolor='black', shrink=0.05)
#grafico.grid()
#fig.savefig("Serie_Anual_15min_"+anio+".png")
# Grafica del Pico Maximo Potencia Aparente x DIA
from matplotlib import ticker
def Grafica_xDia(pi, pf):
y = datos.loc[pi:pf, 'MVA'].resample('D').max()
x = y.index
plt.style.use('fivethirtyeight')
fig = plt.figure()
fig, grafico = plt.subplots(figsize=(30, 5), dpi=100)
grafico.plot(x, y, lw=1.5, label='Potencia Aparente x Dia', marker='o')
grafico.set_xlabel('[ Meses ]') # Add an x-label to the axes.
grafico.set_ylabel('[ MVA ]') # Add a y-label to the axes.
grafico.set_title("POTENCIA APARENTE DIARIA " + anio) # Add a title to the axes.
#grafico.legend(loc='lower left') # Add a legend.
#grafico.grid(visible='True', which='major', axis='both', color='black', alpha=1, linewidth=0.5)
grafico.grid(visible='True', which='major', axis='both', color='black', linewidth=0.5)
grafico.grid(visible='True', which='minor', axis='both', color='black', linewidth=0.5)
x2 = pd.date_range(start=pi+'-01-01', end=pf+'-12-31', periods=5)
grafico.set_xticks(x2)
#grafico.annotate('Pico Max', xy=(01-31 14:45, 75), xytext=(01-31 15:00, 75), arrowprops=dict(facecolor='black', shrink=0.05)
#grafico.grid()
#fig.savefig("Serie_Anual_xDia_"+anio+".png")
# GRAFICA DEL PICO MAXIMO POTENCIA APARENTE (CADA 15 MINUTOS) VENTANA 12 hs ANTES y 12 hs DESPUES
#
def Grafica_Pico_Anual(pi, pf):
indice_max = datos.loc[pi:pf, 'MVA'].idxmax()
delta = pd.Timedelta('12 hours')
indice_mas12 = indice_max + delta
indice_menos12 = indice_max - delta
maximo = datos.loc[indice_menos12:indice_mas12, 'MVA'].max()
y = datos.loc[indice_menos12 : indice_mas12, 'MVA'] # Datos
x = y.index # Tiempo
plt.style.use('fivethirtyeight')
fig = plt.figure()
fig, ax = plt.subplots(figsize=(10, 3), dpi=100) #fig, ax = plt.subplots(figsize=(10, 5), dpi=100)
#Rotulo = 'Pico: ' + str(indice_max) + ' ' + str(maximo)
ax.plot(x, y, lw=1, marker='o') #ax.plot(x, y, lw=1, label=Rotulo, marker='o')
ax.minorticks_on()
#ax.grid(b=True, which='major', color='blue', alpha=1, linewidth=1)
#ax.grid(b=True, which='minor', color='beige', alpha=1, linewidth=1)
# Major Tick Label
# Minor Tick Label
plt.xticks(fontsize=10, rotation=90)
plt.yticks(fontsize=10)
ax.set_xlabel('[ Horas ]', fontsize=10) # Add an x-label to the axes.
ax.set_ylabel('[ MVA ]', fontsize=10) # Add a y-label to the axes.
ax.set_title("PICO MAXIMO POTENCIA APARENTE " + str(maximo) + ' ' + str(indice_max), fontsize=12) # Add a title to the axes.
#ax.legend(loc='lower left', fontsize=10) # Add a legend.
#fig.savefig("Pico_Anual_"+anio+".png")
#print(indice_menos12)
print(indice_max, datos.loc[indice_menos12:indice_mas12, 'MW'].max(), datos.loc[indice_menos12:indice_mas12, 'MVA'].max())
#print(indice_mas12)
#maximo = datos.loc[indice_max:indice_max, 'MVA']
#print(maximo[0])
Grafica_xmin('2014-06-18 12', '2014-06-23 16')
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-41-a46526f9db4c> in <module> ----> 1 Grafica_xmin('2014-06-18 12', '2014-06-23 16') <ipython-input-40-57faf5f979cf> in Grafica_xmin(pi, pf) 13 grafico.set_xlabel('[ Meses ]') # Add an x-label to the axes. 14 grafico.set_ylabel('[ MVA ]') # Add a y-label to the axes. ---> 15 grafico.set_title("POTENCIA APARENTE [cada 15 minutos] " + anio) # Add a title to the axes. 16 #grafico.legend(loc='lower left') # Add a legend. 17 NameError: name 'anio' is not defined
<Figure size 432x288 with 0 Axes>
Grafica_xmin('2014-06-18', '2014-06-18')
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-42-1db7e8722eea> in <module> ----> 1 Grafica_xmin('2014-06-18', '2014-06-18') <ipython-input-40-57faf5f979cf> in Grafica_xmin(pi, pf) 13 grafico.set_xlabel('[ Meses ]') # Add an x-label to the axes. 14 grafico.set_ylabel('[ MVA ]') # Add a y-label to the axes. ---> 15 grafico.set_title("POTENCIA APARENTE [cada 15 minutos] " + anio) # Add a title to the axes. 16 #grafico.legend(loc='lower left') # Add a legend. 17 NameError: name 'anio' is not defined
<Figure size 432x288 with 0 Axes>
# LANZO LAS GRAFICAS
anios = ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021']
Grafica_xSemana(anios[0], anios[-1])
Grafica_Caja(anios[0], anios[-1])
for anio in anios:
Grafica_xmin(anio, anio)
Grafica_Caja(anio, anio)
Grafica_xDia(anio, anio)
Grafica_Pico_Anual(anio, anio)
2010-01-05 14:00:00 36.24 37.32 2011-12-20 13:30:00 39.13 40.2 2012-02-16 14:00:00 42.13 43.18 2013-12-26 15:00:00 41.97 42.7 2014-01-23 14:00:00 48.77 49.73 2015-03-11 14:00:00 44.64 46.34 2016-02-12 13:15:00 45.98 46.79 2017-03-02 13:15:00 45.16 45.48 2018-02-07 13:45:00 46.22 46.35 2019-02-22 14:15:00 45.63 45.77 2020-12-28 13:15:00 41.71 41.74 2021-12-29 14:15:00 48.65 48.67
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
<Figure size 640x480 with 0 Axes>
#
# GENERAR TABLA EXCEL CON LOS DATOS DEPURADOS
#
anios_hist = ['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021']
Trafos = pd.Series([25.0, 25.0, 25.0], index=['TD1', 'TD2', 'TD3'])
POT_INSTALADA = Trafos.sum()
Historica = pd.DataFrame(columns = ['FECHA_HORA', 'P_MW', 'Q_MVAR', 'S_MVA'])
for anio in anios_hist:
#Anio = pd.to_numeric(anio)
fecha_hora_i = datos.loc[anio:anio, 'MVA'].idxmax()
maximo_p = datos.loc[fecha_hora_i, 'MW'].max()
maximo_q = datos.loc[fecha_hora_i, 'MVAR'].max()
maximo_s = datos.loc[fecha_hora_i, 'MVA'].max()
Historica.loc[anio] = [fecha_hora_i, maximo_p, maximo_q, maximo_s]
# Columnas derivadas
Historica['POT_INSTALADA'] = POT_INSTALADA
Historica['CRECIMIENTO_%'] = Historica['S_MVA'].pct_change().mul(100)
Historica['N-1'] = Historica['POT_INSTALADA'] - Trafos.max()
Historica['CARGA_%'] = Historica['S_MVA'] / Historica['POT_INSTALADA'] * 100
Historica['ANIO'] = pd.to_numeric(Historica.index)
nombres_columnas = ['ANIO', 'FECHA_HORA', 'P_MW', 'Q_MVAR', 'S_MVA', 'CRECIMIENTO_%', 'POT_INSTALADA', 'N-1', 'CARGA_%']
Historica = Historica.reindex(columns=nombres_columnas)
Historica
| ANIO | FECHA_HORA | P_MW | Q_MVAR | S_MVA | CRECIMIENTO_% | POT_INSTALADA | N-1 | CARGA_% | |
|---|---|---|---|---|---|---|---|---|---|
| 2010 | 2010 | 2010-01-05 14:00:00 | 36.24 | 8.89 | 37.32 | NaN | 75.00 | 50.00 | 49.76 |
| 2011 | 2011 | 2011-12-20 13:30:00 | 39.13 | 9.23 | 40.20 | 7.72 | 75.00 | 50.00 | 53.60 |
| 2012 | 2012 | 2012-02-16 14:00:00 | 42.13 | 9.47 | 43.18 | 7.41 | 75.00 | 50.00 | 57.57 |
| 2013 | 2013 | 2013-12-26 15:00:00 | 41.97 | 7.88 | 42.70 | -1.11 | 75.00 | 50.00 | 56.93 |
| 2014 | 2014 | 2014-01-23 14:00:00 | 48.67 | 10.21 | 49.73 | 16.46 | 75.00 | 50.00 | 66.31 |
| 2015 | 2015 | 2015-03-11 14:00:00 | 44.64 | 12.43 | 46.34 | -6.82 | 75.00 | 50.00 | 61.79 |
| 2016 | 2016 | 2016-02-12 13:15:00 | 45.93 | 8.94 | 46.79 | 0.97 | 75.00 | 50.00 | 62.39 |
| 2017 | 2017 | 2017-03-02 13:15:00 | 45.16 | 5.41 | 45.48 | -2.80 | 75.00 | 50.00 | 60.64 |
| 2018 | 2018 | 2018-02-07 13:45:00 | 46.22 | 3.40 | 46.35 | 1.91 | 75.00 | 50.00 | 61.80 |
| 2019 | 2019 | 2019-02-22 14:15:00 | 45.63 | 3.57 | 45.77 | -1.25 | 75.00 | 50.00 | 61.03 |
| 2020 | 2020 | 2020-12-28 13:15:00 | 41.71 | 1.59 | 41.74 | -8.80 | 75.00 | 50.00 | 55.65 |
| 2021 | 2021 | 2021-12-29 14:15:00 | 48.65 | 1.51 | 48.67 | 16.60 | 75.00 | 50.00 | 64.89 |
Historica.index
Index(['2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017', '2018',
'2019', '2020', '2021'],
dtype='object')
pd.set_option('display.float_format', '{:.8f}'.format)
import statsmodels.formula.api as smf
lm = smf.ols(formula="S_MVA~ANIO", data = Historica).fit()
lm.summary2()
| Model: | OLS | Adj. R-squared: | 0.259 |
| Dependent Variable: | S_MVA | AIC: | 62.9670 |
| Date: | 2022-06-14 13:43 | BIC: | 63.9368 |
| No. Observations: | 12 | Log-Likelihood: | -29.483 |
| Df Model: | 1 | F-statistic: | 4.842 |
| Df Residuals: | 10 | Prob (F-statistic): | 0.0524 |
| R-squared: | 0.326 | Scale: | 9.5674 |
| Coef. | Std.Err. | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | -1102.6916 | 521.3294 | -2.1152 | 0.0605 | -2264.2860 | 58.9027 |
| ANIO | 0.5692 | 0.2587 | 2.2006 | 0.0524 | -0.0071 | 1.1455 |
| Omnibus: | 1.100 | Durbin-Watson: | 1.424 |
| Prob(Omnibus): | 0.577 | Jarque-Bera (JB): | 0.040 |
| Skew: | 0.056 | Prob(JB): | 0.980 |
| Kurtosis: | 3.260 | Condition No.: | 1176765 |
pd.set_option('display.float_format', '{:.2f}'.format)
Historica['S_MVA_PRED'] = lm.predict(Historica['ANIO'])
nombres_columnas = ['ANIO', 'FECHA_HORA', 'P_MW', 'Q_MVAR', 'S_MVA', 'CRECIMIENTO_%', 'S_MVA_PRED', 'POT_INSTALADA', 'N-1', 'CARGA_%']
Historica = Historica.reindex(columns=nombres_columnas)
Historica
| ANIO | FECHA_HORA | P_MW | Q_MVAR | S_MVA | CRECIMIENTO_% | S_MVA_PRED | POT_INSTALADA | N-1 | CARGA_% | |
|---|---|---|---|---|---|---|---|---|---|---|
| 2010 | 2010 | 2010-01-05 14:00:00 | 36.24 | 8.89 | 37.32 | NaN | 41.39 | 75.00 | 50.00 | 49.76 |
| 2011 | 2011 | 2011-12-20 13:30:00 | 39.13 | 9.23 | 40.20 | 7.72 | 41.96 | 75.00 | 50.00 | 53.60 |
| 2012 | 2012 | 2012-02-16 14:00:00 | 42.13 | 9.47 | 43.18 | 7.41 | 42.53 | 75.00 | 50.00 | 57.57 |
| 2013 | 2013 | 2013-12-26 15:00:00 | 41.97 | 7.88 | 42.70 | -1.11 | 43.10 | 75.00 | 50.00 | 56.93 |
| 2014 | 2014 | 2014-01-23 14:00:00 | 48.67 | 10.21 | 49.73 | 16.46 | 43.67 | 75.00 | 50.00 | 66.31 |
| 2015 | 2015 | 2015-03-11 14:00:00 | 44.64 | 12.43 | 46.34 | -6.82 | 44.24 | 75.00 | 50.00 | 61.79 |
| 2016 | 2016 | 2016-02-12 13:15:00 | 45.93 | 8.94 | 46.79 | 0.97 | 44.81 | 75.00 | 50.00 | 62.39 |
| 2017 | 2017 | 2017-03-02 13:15:00 | 45.16 | 5.41 | 45.48 | -2.80 | 45.38 | 75.00 | 50.00 | 60.64 |
| 2018 | 2018 | 2018-02-07 13:45:00 | 46.22 | 3.40 | 46.35 | 1.91 | 45.95 | 75.00 | 50.00 | 61.80 |
| 2019 | 2019 | 2019-02-22 14:15:00 | 45.63 | 3.57 | 45.77 | -1.25 | 46.51 | 75.00 | 50.00 | 61.03 |
| 2020 | 2020 | 2020-12-28 13:15:00 | 41.71 | 1.59 | 41.74 | -8.80 | 47.08 | 75.00 | 50.00 | 55.65 |
| 2021 | 2021 | 2021-12-29 14:15:00 | 48.65 | 1.51 | 48.67 | 16.60 | 47.65 | 75.00 | 50.00 | 64.89 |
print('Parametros : ', lm.params)
print('R2 : ', lm.rsquared)
Parametros : Intercept -1102.69 ANIO 0.57 dtype: float64 R2 : 0.3262571112710426
#
# AGREGO LOS AÑOS DE PRONOSTICO PROPIAMENTE DICHO
#
#Pronostico = Tablaxls.copy()
pd.set_option('display.float_format', '{:.2f}'.format)
anios_pro = ['2022', '2023', '2024', '2025', '2026']
POT_INSTALADA = Trafos.sum()
Precaucion = POT_INSTALADA - Trafos.max()
Anio = pd.Series(pd.to_numeric(anios_pro), index=anios_pro)
Fecha_Hora = pd.Series(np.nan, index= anios_pro)
P_MW = pd.Series(np.nan, index=anios_pro)
Q_MVAR = pd.Series(np.nan, index=anios_pro)
S_MVA = pd.Series(np.nan, index=anios_pro)
Crecimiento = pd.Series(np.nan, index=anios_pro)
Pronostico = pd.DataFrame({'ANIO':Anio,
'FECHA_HORA':Fecha_Hora,
'P_MW':P_MW,
'Q_MVAR':Q_MVAR,
'S_MVA':S_MVA,
'CRECIMIENTO_%':Crecimiento}, index=anios_pro)
# El MODELO DE REGRESION LINEAL
Pronostico['S_MVA_PRED'] = lm.predict(Pronostico['ANIO']) # Pronostico['S_MVA_PRED'] = 0.51372727*Pronostico["ANIO"] - 991.015000
#
Pronostico['POT_INSTALADA'] = POT_INSTALADA
Pronostico['N-1'] = Pronostico['POT_INSTALADA'] - Trafos.max()
Pronostico['CARGA_%'] = Pronostico['S_MVA_PRED'] / Pronostico['POT_INSTALADA'] * 100
# nombres_columnas = ['FECHA_HORA', 'P_MW', 'Q_MVAR', 'S_MVA', 'Crecimiento %', 'Pot_Instalada', 'N-1', '% Carga']
#Tablaxls = Tablaxls.reindex(columns=nombres_columnas)
Pronostico
| ANIO | FECHA_HORA | P_MW | Q_MVAR | S_MVA | CRECIMIENTO_% | S_MVA_PRED | POT_INSTALADA | N-1 | CARGA_% | |
|---|---|---|---|---|---|---|---|---|---|---|
| 2022 | 2022 | NaN | NaN | NaN | NaN | NaN | 48.22 | 75.00 | 50.00 | 64.30 |
| 2023 | 2023 | NaN | NaN | NaN | NaN | NaN | 48.79 | 75.00 | 50.00 | 65.06 |
| 2024 | 2024 | NaN | NaN | NaN | NaN | NaN | 49.36 | 75.00 | 50.00 | 65.81 |
| 2025 | 2025 | NaN | NaN | NaN | NaN | NaN | 49.93 | 75.00 | 50.00 | 66.57 |
| 2026 | 2026 | NaN | NaN | NaN | NaN | NaN | 50.50 | 75.00 | 50.00 | 67.33 |
#
# CONCATENAR LA TABLA HISTORICA + TABLA PRONOSTICO
#
Tablaxls = pd.concat([Historica,Pronostico], axis = 0)
Tablaxls
| ANIO | FECHA_HORA | P_MW | Q_MVAR | S_MVA | CRECIMIENTO_% | S_MVA_PRED | POT_INSTALADA | N-1 | CARGA_% | |
|---|---|---|---|---|---|---|---|---|---|---|
| 2010 | 2010 | 2010-01-05 14:00:00 | 36.24 | 8.89 | 37.32 | NaN | 41.39 | 75.00 | 50.00 | 49.76 |
| 2011 | 2011 | 2011-12-20 13:30:00 | 39.13 | 9.23 | 40.20 | 7.72 | 41.96 | 75.00 | 50.00 | 53.60 |
| 2012 | 2012 | 2012-02-16 14:00:00 | 42.13 | 9.47 | 43.18 | 7.41 | 42.53 | 75.00 | 50.00 | 57.57 |
| 2013 | 2013 | 2013-12-26 15:00:00 | 41.97 | 7.88 | 42.70 | -1.11 | 43.10 | 75.00 | 50.00 | 56.93 |
| 2014 | 2014 | 2014-01-23 14:00:00 | 48.67 | 10.21 | 49.73 | 16.46 | 43.67 | 75.00 | 50.00 | 66.31 |
| 2015 | 2015 | 2015-03-11 14:00:00 | 44.64 | 12.43 | 46.34 | -6.82 | 44.24 | 75.00 | 50.00 | 61.79 |
| 2016 | 2016 | 2016-02-12 13:15:00 | 45.93 | 8.94 | 46.79 | 0.97 | 44.81 | 75.00 | 50.00 | 62.39 |
| 2017 | 2017 | 2017-03-02 13:15:00 | 45.16 | 5.41 | 45.48 | -2.80 | 45.38 | 75.00 | 50.00 | 60.64 |
| 2018 | 2018 | 2018-02-07 13:45:00 | 46.22 | 3.40 | 46.35 | 1.91 | 45.95 | 75.00 | 50.00 | 61.80 |
| 2019 | 2019 | 2019-02-22 14:15:00 | 45.63 | 3.57 | 45.77 | -1.25 | 46.51 | 75.00 | 50.00 | 61.03 |
| 2020 | 2020 | 2020-12-28 13:15:00 | 41.71 | 1.59 | 41.74 | -8.80 | 47.08 | 75.00 | 50.00 | 55.65 |
| 2021 | 2021 | 2021-12-29 14:15:00 | 48.65 | 1.51 | 48.67 | 16.60 | 47.65 | 75.00 | 50.00 | 64.89 |
| 2022 | 2022 | NaN | NaN | NaN | NaN | NaN | 48.22 | 75.00 | 50.00 | 64.30 |
| 2023 | 2023 | NaN | NaN | NaN | NaN | NaN | 48.79 | 75.00 | 50.00 | 65.06 |
| 2024 | 2024 | NaN | NaN | NaN | NaN | NaN | 49.36 | 75.00 | 50.00 | 65.81 |
| 2025 | 2025 | NaN | NaN | NaN | NaN | NaN | 49.93 | 75.00 | 50.00 | 66.57 |
| 2026 | 2026 | NaN | NaN | NaN | NaN | NaN | 50.50 | 75.00 | 50.00 | 67.33 |
Ver de hacer con seaborn
# Grafica anual de la Potencia Aparente cada 15 minutos
# (Trafos + Generacion)
def Grafica_Hist_Pred():
plt.style.use('fivethirtyeight')
#y = Tablaxls.loc['2010':'2021', 'S_MVA']
#x_y = Tablaxls.loc['2010':'2021', 'ANIO']
y = Tablaxls.loc[:, 'S_MVA']
pred = Tablaxls.loc[:, 'S_MVA_PRED']
p_inst = Tablaxls.loc[:, 'POT_INSTALADA']
precau = Tablaxls.loc[:, 'N-1']
x = Tablaxls.loc[:, 'ANIO']
fig = plt.figure()
fig, grafico = plt.subplots(figsize=(15, 5), dpi=100) #fig, grafico = plt.subplots(figsize=(15, 5), dpi=100)
#grafico.plot(x, y, lw=1, label='Potencia Aparente', marker='o')
grafico.plot(x, y, lw=3, label='Pot. Historica', marker='o', color='k')
grafico.plot(x, pred, lw=3, label='Tend. Lineal', marker='o', linestyle='dotted', color='b')
grafico.plot(x, p_inst, lw=2, label='Pot.Instalada', color='r')
grafico.plot(x, precau, lw=2, label='Precaucion N-1', color='y')
grafico.set_ylim ([20,90])
grafico.set_xlabel('[ Años ]') # Add an x-label to the axes.
grafico.set_ylabel('[ MVA ]') # Add a y-label to the axes.
grafico.set_title("ET San Francisco: Demanda Historica y Pronostico al 2026 ") # Add a title to the axes.
grafico.legend(loc='lower right') # Add a legend.
#grafico.annotate('Pico Max', xy=(01-31 14:45, 75), xytext=(01-31 15:00, 75), arrowprops=dict(facecolor='black', shrink=0.05)
#grafico.grid()
#fig.savefig("Serie_Anual_15min_"+anio+".png")
Grafica_Hist_Pred()
<Figure size 640x480 with 0 Axes>
# Grafica anual de la Potencia Aparente cada 15 minutos
# (Trafos + Generacion)
def Grafica_Hist_Pred2():
plt.style.use('fivethirtyeight')
#y = Tablaxls.loc['2010':'2021', 'S_MVA']
#x_y = Tablaxls.loc['2010':'2021', 'ANIO']
y = Tablaxls.loc[:, 'S_MVA']
pred = Tablaxls.loc[:, 'S_MVA_PRED']
p_inst = Tablaxls.loc[:, 'POT_INSTALADA']
precau = Tablaxls.loc[:, 'N-1']
x = Tablaxls.loc[:, 'ANIO']
#fig = plt.figure()
#fig, grafico = plt.subplots(figsize=(15, 5), dpi=100)
fig, grafico = plt.subplots(figsize=(7, 4))
#grafico.plot(x, y, lw=1, label='Potencia Aparente', marker='o')
grafico.plot(x, y, lw=2, label='Pot. Historica', marker='o', color='k')
grafico.plot(x, pred, lw=2, label='Tend. Lineal', marker='o', linestyle='dotted', color='b')
#grafico.plot(x, p_inst, lw=2, label='Pot.Instalada', color='r')
grafico.plot(x, precau, lw=2, label='Precaucion N-1', color='y')
#grafico.set_ylim ([20,90])
ax.minorticks_on()
ax.grid(b=True, which='major', color='blue', alpha=1, linewidth=1)
ax.grid(b=True, which='minor', color='beige', alpha=1, linewidth=1)
# Major Tick Label
# Minor Tick Label
#plt.xticks(fontsize=10)
#x_rotulos=[2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026]
x_rotulos = np.arange(2010,2027,1)
plt.xticks(ticks=x, labels=x_rotulos, fontsize='x-small')
plt.yticks(fontsize=10)
grafico.set_xlabel('[ Años ]', fontsize=10) # Add an x-label to the axes.
grafico.set_ylabel('[ MVA ]', fontsize=10) # Add a y-label to the axes.
grafico.set_title("ET San Francisco: Demanda Historica y Pronostico al 2026 ", fontsize=12) # Add a title to the axes.
grafico.legend(loc='lower right', fontsize=10) # Add a legend.
#grafico.annotate('Pico Max', xy=(01-31 14:45, 75), xytext=(01-31 15:00, 75), arrowprops=dict(facecolor='black', shrink=0.05)
#grafico.grid()
#fig.savefig("Serie_Anual_15min_"+anio+".png")
Grafica_Hist_Pred2()
# Grafica anual de la Potencia Aparente cada 15 minutos
# (Trafos + Generacion)
def Grafica_Hist_Pred_Seaborn():
plt.style.use('fivethirtyeight')
#y = Tablaxls.loc['2010':'2021', 'S_MVA']
#x_y = Tablaxls.loc['2010':'2021', 'ANIO']
y = Tablaxls.loc[:, 'S_MVA']
pred = Tablaxls.loc[:, 'S_MVA_PRED']
p_inst = Tablaxls.loc[:, 'POT_INSTALADA']
precau = Tablaxls.loc[:, 'N-1']
x = Tablaxls.loc[:, 'ANIO']
#fig = plt.figure()
#fig, grafico = plt.subplots(figsize=(15, 5), dpi=100)
fig, grafico = plt.subplots(figsize=(7, 4))
sns.lineplot(x=x, y=y, err_style="bars", ci=68)
Grafica_Hist_Pred_Seaborn()
Tablaxls.info()
<class 'pandas.core.frame.DataFrame'> Index: 17 entries, 2010 to 2026 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ANIO 17 non-null int64 1 FECHA_HORA 12 non-null object 2 P_MW 12 non-null float64 3 Q_MVAR 12 non-null float64 4 S_MVA 12 non-null float64 5 CRECIMIENTO_% 11 non-null float64 6 S_MVA_PRED 17 non-null float64 7 POT_INSTALADA 17 non-null float64 8 N-1 17 non-null float64 9 CARGA_% 17 non-null float64 dtypes: float64(8), int64(1), object(1) memory usage: 2.0+ KB
Tablaxls["RSE"] = (Tablaxls["S_MVA"]-Tablaxls["S_MVA_PRED"])**2
Tablaxls
| ANIO | FECHA_HORA | P_MW | Q_MVAR | S_MVA | CRECIMIENTO_% | S_MVA_PRED | POT_INSTALADA | N-1 | CARGA_% | RSE | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 | 2010 | 2010-01-05 14:00:00 | 36.24 | 8.89 | 37.32 | NaN | 40.82 | 75.00 | 50.00 | 49.76 | 12.22 |
| 2011 | 2011 | 2011-12-20 13:30:00 | 39.13 | 9.23 | 40.20 | 7.72 | 42.11 | 75.00 | 50.00 | 53.60 | 3.64 |
| 2012 | 2012 | 2012-02-16 14:00:00 | 42.13 | 9.47 | 43.18 | 7.41 | 43.40 | 75.00 | 50.00 | 57.57 | 0.05 |
| 2013 | 2013 | 2013-12-26 15:00:00 | 41.97 | 7.88 | 42.70 | -1.11 | 44.69 | 75.00 | 50.00 | 56.93 | 3.98 |
| 2014 | 2014 | 2014-01-23 14:00:00 | 48.67 | 10.21 | 49.73 | 16.46 | 45.99 | 75.00 | 50.00 | 66.31 | 14.01 |
| 2015 | 2015 | 2015-03-11 14:00:00 | 44.64 | 12.43 | 46.34 | -6.82 | 47.28 | 75.00 | 50.00 | 61.79 | 0.88 |
| 2016 | 2016 | 2016-02-12 13:15:00 | 45.93 | 8.94 | 46.79 | 0.97 | 48.57 | 75.00 | 50.00 | 62.39 | 3.18 |
| 2017 | 2017 | 2017-01-27 09:30:00 | 2.95 | 42.47 | 75.78 | 61.96 | 49.87 | 75.00 | 50.00 | 101.04 | 671.54 |
| 2018 | 2018 | 2018-02-07 13:45:00 | 46.22 | 3.40 | 46.35 | -38.84 | 51.16 | 75.00 | 50.00 | 61.80 | 23.12 |
| 2019 | 2019 | 2019-02-22 14:15:00 | 45.63 | 3.57 | 45.77 | -1.25 | 52.45 | 75.00 | 50.00 | 61.03 | 44.64 |
| 2020 | 2020 | 2020-12-28 13:15:00 | 41.71 | 1.59 | 41.74 | -8.80 | 53.74 | 75.00 | 50.00 | 55.65 | 144.10 |
| 2021 | 2021 | 2021-05-04 11:30:00 | 26.85 | 52.78 | 59.22 | 41.88 | 55.04 | 75.00 | 50.00 | 78.96 | 17.50 |
| 2022 | 2022 | NaN | NaN | NaN | NaN | NaN | 47.74 | 75.00 | 50.00 | 63.66 | NaN |
| 2023 | 2023 | NaN | NaN | NaN | NaN | NaN | 48.26 | 75.00 | 50.00 | 64.34 | NaN |
| 2024 | 2024 | NaN | NaN | NaN | NaN | NaN | 48.77 | 75.00 | 50.00 | 65.03 | NaN |
| 2025 | 2025 | NaN | NaN | NaN | NaN | NaN | 49.28 | 75.00 | 50.00 | 65.71 | NaN |
| 2026 | 2026 | NaN | NaN | NaN | NaN | NaN | 49.80 | 75.00 | 50.00 | 66.40 | NaN |
plt.hist((Tablaxls["S_MVA"]-Tablaxls["S_MVA_PRED"]))
(array([1., 2., 5., 1., 2., 0., 0., 0., 0., 1.]),
array([-12.00425408, -8.21241492, -4.42057576, -0.6287366 ,
3.16310256, 6.95494172, 10.74678089, 14.53862005,
18.33045921, 22.12229837, 25.91413753]),
<BarContainer object of 10 artists>)
Tablaxls.info()
<class 'pandas.core.frame.DataFrame'> Index: 17 entries, 2010 to 2026 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ANIO 17 non-null int64 1 FECHA_HORA 12 non-null object 2 P_MW 12 non-null float64 3 Q_MVAR 12 non-null float64 4 S_MVA 12 non-null float64 5 CRECIMIENTO_% 11 non-null float64 6 S_MVA_PRED 17 non-null float64 7 POT_INSTALADA 17 non-null float64 8 N-1 17 non-null float64 9 CARGA_% 17 non-null float64 10 RSE 12 non-null float64 dtypes: float64(9), int64(1), object(1) memory usage: 1.6+ KB